<script  setup>
import { computed, provide, ref, watchEffect } from 'vue'
const props = defineProps( {
    data: Array,
    edit: Boolean,
    request:Function
  } 
)

const formModel = ref({
  model: [],
})

const form = ref()

const formProps = ref(new Set())

const tableData = computed(() => formModel.value.model.map(({ data }) => {
  return {...data,isEditing: false}
}))

const resultData = computed(() => {
  return formModel.value.model.reduce((resultData, model) => {
    if (model.isNew) {
      return resultData
    }
    resultData.push({
      ...model.data,
    })
    return resultData
  }, [])
})

const convertFormModel = (data) =>
  data.map(
    (row)=> ({
      data: { ...row },
      formData: { ...row },
      isEditing: false,
      isNew: false,
    })
  )

watchEffect(async () => {
  const model = [...props.data]
  if (typeof props.request === 'function') {
    model.push(...(await Promise.resolve(props.request())))
  }
  formModel.value.model = convertFormModel(model)
})

const generateValidateFields = (index) =>
  Array.from(formProps.value).map((prop) => `model.${index}.formData.${prop}`)

const startEditable = (index) => {
  formModel.value.model[index].isEditing = true
}
const editable = (index) => {
  // formModel.value.model[index].isEditing = true
}

const deleteRow = (index) => {
  formModel.value.model.splice(index, 1)
}

const addRow = (row) => {
  formModel.value.model.push({
    data: { ...row },
    formData: { ...row },
    isEditing: true,
    isNew: true,
  })
}

const cancelEditable = (index) => {
  if (!form.value) {
    return
  }

  form.value.resetFields && form.value.resetFields(generateValidateFields(index))
  const formModelItem = formModel.value.model[index]
  formModelItem.formData = { ...formModelItem.data }
  if (formModelItem.isNew) {
    formModel.value.model.splice(index, 1)
  } else {
    formModelItem.isEditing = false
  }
}

const saveEditable = (index) => {
  if (!form.value) {
    return
  }

  form.value.validateField &&
    form.value.validateField(generateValidateFields(index), (validated) => {
      if (!validated) {
        return
      }
      const formModelItem = formModel.value.model[index]
      formModelItem.data = { ...formModelItem.formData }
      formModelItem.isEditing = false
      formModelItem.isNew = false
    })
}

const editActions = {
  addRow,
  deleteRow,
  startEditable,
  cancelEditable,
  saveEditable,
}

provide('formModel', formModel)

provide('formProps', formProps)

provide('editActions', editActions)

defineExpose({
  resultData,
  editActions,
});
</script>

<template>
  <div>
    <el-form ref="form" :model="formModel">
      <el-table v-bind="$attrs" :data="tableData">
        <slot> </slot>
      </el-table>
    </el-form>
  </div>
</template>
